package com.bauer.base.jvm;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author ：rui.wei
 * @Date ：Created in 17:50 2019/2/11
 * @Description：
 */
public class OOMDemo {


    /**
     * java oom 错误  当使用内存超出最大值 vm args : -Xmx20M -Xms20M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails
     * -XX:MaxDirectMemorySize=10M
     */
    public static void main(String[] args) throws Exception {
        heapOOM();
    }

    /**
     * 堆上oom
     */
    public static void heapOOM() {
        List<byte[]> list = new ArrayList<>();
        while (true) {
            list.add(new byte[1024]);
        }
    }

    /**
     * 常量池oom   String.intern 方法可以在运行时向常量池中插入数据(常量池中不存在是插入，存在返回当前的引用)
     * 1.8将常量池从方法区中移入了  堆中  所以以下方法抛出的oom OutOfMemoryError: Java heap space
     * 1.7 OutOfMemoryError: PermGen space
     */
    public static void constantOOM() {

        List<String> list = new ArrayList<>();

        while (true) {
            int i = 1;
            list.add(String.valueOf(i).intern());
            i++;
        }
    }

    /**
     * 直接内存oom
     * OutOfMemoryError
     * @throws IllegalAccessException
     */
    public static void directMemoryOOM() throws IllegalAccessException {
        Field field = Unsafe.class.getDeclaredFields()[0];
        field.setAccessible(true);
        Unsafe unsafe = (Unsafe) field.get(null);
        while (true) {
            unsafe.allocateMemory(1024 * 1024);
        }
    }
}
